/**
 * Git 提交消息生成器
 * 基于Conventional Commits规范自动生成标准化的提交消息
 */

// 提交类型枚举
export enum CommitType {
  FEAT = 'feat',
  FIX = 'fix',
  DOCS = 'docs',
  STYLE = 'style',
  REFACTOR = 'refactor',
  TEST = 'test',
  CHORE = 'chore',
  PERF = 'perf',
  CI = 'ci',
  BUILD = 'build',
  REVERT = 'revert',
  HOTFIX = 'hotfix',
  RELEASE = 'release',
  MERGE = 'merge',
  INIT = 'init',
}

// 提交消息配置接口
export interface CommitMessageConfig {
  type: CommitType;
  scope?: string;
  description: string;
  body?: string | string[];
  footer?: string | string[];
  breakingChange?: string;
  issues?: number[];
}

// 预定义的提交消息模板
export class CommitMessageTemplates {
  /**
   * 功能开发模板
   */
  static feature(description: string, details: string[], scope?: string): CommitMessageConfig {
    return {
      type: CommitType.FEAT,
      scope,
      description,
      body: details,
    };
  }

  /**
   * Bug修复模板
   */
  static bugFix(
    description: string,
    problem: string,
    solution: string,
    scope?: string,
    issues?: number[]
  ): CommitMessageConfig {
    const body = [`问题描述：${problem}`, '', `解决方案：${solution}`];

    return {
      type: CommitType.FIX,
      scope,
      description,
      body,
      issues,
    };
  }

  /**
   * 文档更新模板
   */
  static documentation(description: string, updates: string[]): CommitMessageConfig {
    return {
      type: CommitType.DOCS,
      description,
      body: updates,
    };
  }

  /**
   * 重构模板
   */
  static refactor(
    description: string,
    reason: string,
    changes: string[],
    scope?: string,
    isBreaking?: string
  ): CommitMessageConfig {
    const body = [`重构原因：${reason}`, '', '主要变化：', ...changes.map(change => `- ${change}`)];

    return {
      type: CommitType.REFACTOR,
      scope,
      description,
      body,
      breakingChange: isBreaking,
    };
  }

  /**
   * 性能优化模板
   */
  static performance(
    description: string,
    optimizations: string[],
    improvements: string[],
    scope?: string
  ): CommitMessageConfig {
    const body = [
      '优化内容：',
      ...optimizations.map(opt => `- ${opt}`),
      '',
      '性能提升：',
      ...improvements.map(imp => `- ${imp}`),
    ];

    return {
      type: CommitType.PERF,
      scope,
      description,
      body,
    };
  }

  /**
   * 测试模板
   */
  static test(description: string, testTypes: string[], scope?: string): CommitMessageConfig {
    return {
      type: CommitType.TEST,
      scope,
      description,
      body: testTypes,
    };
  }

  /**
   * 依赖更新模板
   */
  static dependencies(action: '更新' | '添加' | '移除', packages: string[]): CommitMessageConfig {
    return {
      type: CommitType.CHORE,
      scope: 'deps',
      description: `${action}依赖包`,
      body: packages.map(pkg => `- ${pkg}`),
    };
  }

  /**
   * CI/CD模板
   */
  static ci(description: string, changes: string[]): CommitMessageConfig {
    return {
      type: CommitType.CI,
      description,
      body: changes,
    };
  }

  /**
   * 紧急修复模板
   */
  static hotfix(
    description: string,
    issue: string,
    fix: string,
    affectedVersions?: string
  ): CommitMessageConfig {
    const body = [`紧急修复：${issue}`, '', `修复内容：${fix}`];

    if (affectedVersions) {
      body.push('', `影响版本：${affectedVersions}`);
    }

    return {
      type: CommitType.HOTFIX,
      description,
      body,
    };
  }

  /**
   * 版本发布模板
   */
  static release(
    version: string,
    features: string[],
    fixes: string[],
    breaking?: string[]
  ): CommitMessageConfig {
    const body: string[] = [];

    if (features.length > 0) {
      body.push('新功能：', ...features.map(f => `- ${f}`), '');
    }

    if (fixes.length > 0) {
      body.push('Bug修复：', ...fixes.map(f => `- ${f}`), '');
    }

    let breakingChange: string | undefined;
    if (breaking && breaking.length > 0) {
      breakingChange = breaking.join('\n');
    }

    return {
      type: CommitType.RELEASE,
      description: `发布版本 ${version}`,
      body: body.slice(0, -1), // 移除最后的空行
      breakingChange,
    };
  }

  /**
   * Agent自动化提交模板
   */
  static automated(
    action: string,
    details: string[],
    type: CommitType = CommitType.FEAT
  ): CommitMessageConfig {
    return {
      type,
      description: `${action} - 自动化操作`,
      body: [
        '自动化执行的操作：',
        ...details.map(detail => `- ${detail}`),
        '',
        `执行时间：${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}`,
      ],
    };
  }
}

// 提交消息生成器类
export class CommitMessageGenerator {
  /**
   * 根据配置生成完整的提交消息
   */
  static generate(config: CommitMessageConfig): string {
    const parts: string[] = [];

    // 构建标题
    let header: string = config.type;
    if (config.scope) {
      header += `(${config.scope})`;
    }
    header += `: ${config.description}`;
    parts.push(header);

    // 添加正文
    if (config.body) {
      parts.push(''); // 空行分隔
      if (typeof config.body === 'string') {
        parts.push(config.body);
      } else {
        parts.push(...config.body);
      }
    }

    // 添加破坏性变更
    if (config.breakingChange) {
      parts.push('');
      parts.push(`BREAKING CHANGE: ${config.breakingChange}`);
    }

    // 添加页脚
    if (config.footer) {
      parts.push('');
      if (typeof config.footer === 'string') {
        parts.push(config.footer);
      } else {
        parts.push(...config.footer);
      }
    }

    // 添加关联Issue
    if (config.issues && config.issues.length > 0) {
      parts.push('');
      if (config.issues.length === 1) {
        parts.push(`Closes #${config.issues[0]}`);
      } else {
        parts.push(`Closes ${config.issues.map(issue => `#${issue}`).join(', ')}`);
      }
    }

    return parts.join('\n');
  }

  /**
   * 生成简短的提交消息（仅标题）
   */
  static generateShort(type: CommitType, description: string, scope?: string): string {
    let message: string = type;
    if (scope) {
      message += `(${scope})`;
    }
    message += `: ${description}`;
    return message;
  }

  /**
   * 验证提交消息格式
   */
  static validate(message: string): { valid: boolean; errors: string[] } {
    const errors: string[] = [];
    const lines = message.split('\n');
    const header: string = lines[0] || '';

    // 检查标题格式
    const headerRegex =
      /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert|hotfix|release|merge|init)(\(.+\))?: .{1,72}$/;
    if (!headerRegex.test(header)) {
      errors.push('标题格式不正确，应该是: <type>[optional scope]: <description>');
    }

    // 检查标题长度
    if (header.length > 72) {
      errors.push('标题长度不应超过72个字符');
    }

    // 检查是否以句号结尾
    if (header.endsWith('.') || header.endsWith('。')) {
      errors.push('标题不应以句号结尾');
    }

    // 检查正文格式
    if (lines.length > 1) {
      if (lines[1] !== '') {
        errors.push('标题和正文之间应该有空行');
      }

      // 检查正文行长度
      for (let i = 2; i < lines.length; i++) {
        if (lines[i] && lines[i]!.length > 72) {
          errors.push(`第${i + 1}行长度超过72个字符`);
        }
      }
    }

    return {
      valid: errors.length === 0,
      errors,
    };
  }

  /**
   * 从Git日志中解析提交类型统计
   */
  static parseCommitStats(gitLog: string): Record<CommitType, number> {
    const stats = Object.values(CommitType).reduce(
      (acc, type) => {
        acc[type] = 0;
        return acc;
      },
      {} as Record<CommitType, number>
    );

    const lines = gitLog.split('\n');
    lines.forEach(line => {
      const match = line.match(/^([a-z]+)(\(.+\))?: /);
      if (match) {
        const type = match[1] as CommitType;
        if (Object.values(CommitType).includes(type)) {
          stats[type]++;
        }
      }
    });

    return stats;
  }
}

// 常用的提交消息快捷生成函数
export const commitMessages = {
  // 功能开发
  addFeature: (feature: string, details: string[] = [], scope?: string) =>
    CommitMessageGenerator.generate(
      CommitMessageTemplates.feature(`添加${feature}`, details, scope)
    ),

  // Bug修复
  fixBug: (bug: string, solution: string, scope?: string, issues?: number[]) =>
    CommitMessageGenerator.generate(
      CommitMessageTemplates.bugFix(`修复${bug}`, bug, solution, scope, issues)
    ),

  // 文档更新
  updateDocs: (updates: string[]) =>
    CommitMessageGenerator.generate(CommitMessageTemplates.documentation('更新项目文档', updates)),

  // 重构代码
  refactorCode: (component: string, reason: string, changes: string[], scope?: string) =>
    CommitMessageGenerator.generate(
      CommitMessageTemplates.refactor(`重构${component}`, reason, changes, scope)
    ),

  // 性能优化
  optimizePerformance: (
    area: string,
    optimizations: string[],
    improvements: string[],
    scope?: string
  ) =>
    CommitMessageGenerator.generate(
      CommitMessageTemplates.performance(`优化${area}性能`, optimizations, improvements, scope)
    ),

  // 添加测试
  addTests: (testArea: string, types: string[], scope?: string) =>
    CommitMessageGenerator.generate(
      CommitMessageTemplates.test(`添加${testArea}测试`, types, scope)
    ),

  // 更新依赖
  updateDeps: (packages: string[]) =>
    CommitMessageGenerator.generate(CommitMessageTemplates.dependencies('更新', packages)),

  // Agent自动化操作
  automatedTask: (task: string, details: string[]) =>
    CommitMessageGenerator.generate(CommitMessageTemplates.automated(task, details)),

  // 简短消息
  quick: {
    feat: (desc: string, scope?: string) =>
      CommitMessageGenerator.generateShort(CommitType.FEAT, desc, scope),
    fix: (desc: string, scope?: string) =>
      CommitMessageGenerator.generateShort(CommitType.FIX, desc, scope),
    docs: (desc: string) => CommitMessageGenerator.generateShort(CommitType.DOCS, desc),
    style: (desc: string) => CommitMessageGenerator.generateShort(CommitType.STYLE, desc),
    refactor: (desc: string, scope?: string) =>
      CommitMessageGenerator.generateShort(CommitType.REFACTOR, desc, scope),
    test: (desc: string, scope?: string) =>
      CommitMessageGenerator.generateShort(CommitType.TEST, desc, scope),
    chore: (desc: string) => CommitMessageGenerator.generateShort(CommitType.CHORE, desc),
  },
};

// 导出默认配置
export default CommitMessageGenerator;
